package com.twb.core.util;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.handler.inter.IExcelDictHandler;
import cn.afterturn.easypoi.handler.inter.IWriter;

import com.twb.core.base.entity.vo.PageVo;
import com.twb.core.base.entity.vo.TableHeader;
import com.twb.core.exception.ServiceException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Class<?>Name ExcelUtils
 * 
 * @Description Excel工具类
 * @author DSY
 * @date 2020年12月28日 上午10:11:00
 */
public class ExcelUtils {

	/**
	 * @Title exportExcel
	 * @Description 根据pageVo导出Excel
	 * @param vo
	 * @param fileName
	 * @param list
	 * @param clazz
	 * @param response
	 * @AuthorOriginally DSY
	 * @date 2022年7月29日 下午5:03:48
	 */
	public static <T> void exportExcel(PageVo vo,String fileName, List<T> list, Class<T> clazz, HttpServletResponse response) {
		exportExcel(vo,fileName, list, clazz, response, null);
	}
	
	/**
	 * @Title exportExcel
	 * @Description 根据pageVo导出Excel
	 * @param vo
	 * @param fileName
	 * @param list
	 * @param clazz
	 * @param response
	 * @param dictHandler
	 * @AuthorOriginally DSY
	 * @date 2022年8月22日 下午5:29:31
	 */
	public static <T> void exportExcel(PageVo vo,String fileName, List<T> list, Class<T> clazz, HttpServletResponse response, IExcelDictHandler dictHandler) {
		if(vo.getHeaders() == null || vo.getHeaders().isEmpty()) {
			exportExcel(fileName, list, clazz, response, dictHandler);
		}else {
			exportExcelForTH(fileName, list, vo.getHeaders(), response,dictHandler);
		}
	}
	/**
	 * @Title exportExcel
	 * @Description 导出Excel
	 * @param fileName 文件名
	 * @param list     导出数据
	 * @param clazz    导出对象
	 * @throws IOException
	 * @author DSY
	 * @date 2020年12月28日 上午10:26:42
	 */
	public static <T> void exportExcel(String fileName, List<T> list, Class<T> clazz, HttpServletResponse response) {
		exportExcel(fileName, list, clazz, response, null);
	}

	/**
	 * @Title exportExcel
	 * @Description 导出Excel
	 * @param fileName    文件名
	 * @param list        导出数据
	 * @param clazz       导出对象
	 * @param response
	 * @param dictHandler 字典处理类
	 * @author DSY
	 * @date 2021年2月2日 下午2:23:25
	 */
	public static <T> void exportExcel(String fileName, List<T> list, Class<T> clazz, HttpServletResponse response, IExcelDictHandler dictHandler) {
		try {
			if (CollectionUtils.isEmpty(list)) {
				throw new ServiceException("导出数据为空");
			}
			ExportParams exportParams = new ExportParams(fileName, fileName);
			exportParams.setType(ExcelType.XSSF);
			if (dictHandler != null) {
				exportParams.setDictHandler(dictHandler);
			}
			exportParams.setStyle(DefaultExcelExportStyler.class);
			Workbook workbook = ExcelExportUtil.exportExcel(exportParams, clazz, list);
			downLoadExcel(fileName, response, workbook);
		} catch (Exception e) {
			// 重置response
			// response.reset();
			/*
			 * response.setContentType("application/json"); response.setCharacterEncoding("utf-8"); Result<Object> failure = Results.failure(String.format("%s：%s", "导出失败", e.getMessage())); response.getWriter().println(JSON.toJSONString(failure));
			 */
			throw new ServiceException(e.getMessage());
		}
	}
	/**
	 * @Title exportExcel
	 * @Description 动态表头导出
	 * @param <T>
	 * @param fileName 文件名
	 * @param list     导出数据
	 * @param headers  表头
	 * @param response 响应对象
	 * @author DHL
	 * @date 2021年3月4日 下午4:45:08
	 */
	public static <T> void exportExcelForTH(String fileName, List<T> list, List<TableHeader> headers, HttpServletResponse response) {
		exportExcelForTH(fileName, list, headers, response, null);
	}

	/**
	 * @Title exportExcel
	 * @Description 动态表头导出
	 * @param <T>
	 * @param fileName    文件名
	 * @param list        导出数据
	 * @param headers     表头
	 * @param response    响应对象
	 * @param dictHandler 字典处理
	 * @author DHL
	 * @date 2021年3月7日 下午5:50:33
	 */
	public static <T> void exportExcelForTH(String fileName, List<T> list, List<TableHeader> headers, HttpServletResponse response, IExcelDictHandler dictHandler) {
		if(headers == null || headers.isEmpty()) {
			throw new ServiceException("Excel导出失败:表头不能为空");
		}
		List<ExcelExportEntity> hs = new ArrayList<ExcelExportEntity>();
		for (TableHeader t : headers) {
			ExcelExportEntity exportEntity = t.convertExcelExportEntity();
			if(exportEntity != null) {
				hs.add(exportEntity);
			}
			hs.add(exportEntity);
		}
		exportExcel(fileName, list, hs, response,dictHandler);
	}
	/**
	 * @Title exportExcel
	 * @Description 动态表头导出
	 * @param <T>
	 * @param fileName 文件名
	 * @param list     导出数据
	 * @param headers  表头
	 * @param response 响应对象
	 * @author DHL
	 * @date 2021年3月4日 下午4:45:08
	 */
	public static <T> void exportExcel(String fileName, List<T> list, List<ExcelExportEntity> headers, HttpServletResponse response) {
		exportExcel(fileName, list, headers, response, null);
	}

	/**
	 * @Title exportExcel
	 * @Description 动态表头导出
	 * @param <T>
	 * @param fileName    文件名
	 * @param list        导出数据
	 * @param headers     表头
	 * @param response    响应对象
	 * @param dictHandler 字典处理
	 * @author DHL
	 * @date 2021年3月7日 下午5:50:33
	 */
	public static <T> void exportExcel(String fileName, List<T> list, List<ExcelExportEntity> headers, HttpServletResponse response, IExcelDictHandler dictHandler) {
		try {
			if (CollectionUtils.isEmpty(list)) {
				throw new ServiceException("导出数据为空");
			}

			ExportParams exportParams = new ExportParams(fileName, fileName);
			exportParams.setType(ExcelType.XSSF);

			if (dictHandler != null) {
				exportParams.setDictHandler(dictHandler);
			}
			exportParams.setStyle(DefaultExcelExportStyler.class);
			Workbook workbook = ExcelExportUtil.exportExcel(exportParams, headers, list);

			downLoadExcel(fileName, response, workbook);
		} catch (Exception e) {
			throw new ServiceException(e.getMessage());
		}
	}

	/**
	 * @Title exportExcel
	 * @Description 多SHEET导出
	 * @param <T>
	 * @param fileName
	 * @param sheetsList
	 * @param response
	 * @author DHL
	 * @date 2021年4月21日 上午11:31:53
	 */
	public static <T> void exportExcel(String fileName, List<Map<String, Object>> sheetsList, HttpServletResponse response) {
		try {
			if (CollectionUtils.isEmpty(sheetsList)) {
				throw new ServiceException("导出数据为空");
			}

			Workbook workbook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.XSSF);

			downLoadExcel(fileName, response, workbook);
		} catch (Exception e) {
			throw new ServiceException(e.getMessage());
		}
	}

	/**
	 * @Title exportBigExcel
	 * @Description 大数据导出
	 * @param <T>
	 * @param fileName
	 * @param clazz
	 * @param dictHandler
	 * @return
	 * @author DHL
	 * @date 2021年7月2日 下午2:29:05
	 */
	public static <T> IWriter<Workbook> exportBigExcel(String fileName, Class<T> clazz, IExcelDictHandler dictHandler) {
		try {
			ExportParams exportParams = new ExportParams(fileName, fileName);
			exportParams.setType(ExcelType.XSSF);

			if (dictHandler != null) {
				exportParams.setDictHandler(dictHandler);
			}
			exportParams.setStyle(DefaultExcelExportStyler.class);
			IWriter<Workbook> exportBigExcel = ExcelExportUtil.exportBigExcel(exportParams, clazz);
			
			return exportBigExcel;

		} catch (Exception e) {
			throw new ServiceException(e.getMessage());
		}
	}
	
	/**
	 * @Title exportBigExcel
	 * @Description 大数据导出 - 自定义表头
	 * @param <T>
	 * @param fileName
	 * @param headers
	 * @param dictHandler
	 * @return
	 * @author DHL
	 * @date 2021年11月18日 下午5:10:13
	 */
	public static <T> IWriter<Workbook> exportBigExcel(String fileName, List<ExcelExportEntity> headers, IExcelDictHandler dictHandler) {
		try {
			ExportParams exportParams = new ExportParams(fileName, fileName);
			exportParams.setType(ExcelType.XSSF);

			if (dictHandler != null) {
				exportParams.setDictHandler(dictHandler);
			}
			exportParams.setStyle(DefaultExcelExportStyler.class);
			IWriter<Workbook> exportBigExcel = ExcelExportUtil.exportBigExcel(exportParams, headers);
			
			return exportBigExcel;

		} catch (Exception e) {
			throw new ServiceException(e.getMessage());
		}
	}
	
	/**
	 * @Title exportBigExcel
	 * @Description 大数据导出 - 自定义表头
	 * @param <T>
	 * @param exportParams
	 * @param headers
	 * @param dictHandler
	 * @return
	 * @AuthorOriginally DHL
	 * @date 2021年12月28日 下午10:03:29
	 */
	public static <T> IWriter<Workbook> exportBigExcel(ExportParams exportParams, List<ExcelExportEntity> headers, IExcelDictHandler dictHandler) {
		try {
			exportParams.setType(ExcelType.XSSF);

			if (dictHandler != null) {
				exportParams.setDictHandler(dictHandler);
			}
			exportParams.setStyle(DefaultExcelExportStyler.class);
			IWriter<Workbook> exportBigExcel = ExcelExportUtil.exportBigExcel(exportParams, headers);
			
			return exportBigExcel;

		} catch (Exception e) {
			throw new ServiceException(e.getMessage());
		}
	}

	/**
	 * @Title downLoadExcel
	 * @Description 下载Excel
	 * @param fileName
	 * @param response
	 * @param workbook
	 * @throws IOException
	 * @author DSY
	 * @date 2021年2月2日 上午10:28:29
	 */
	public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws IOException {
		try {
			response.setCharacterEncoding("UTF-8");
			
			//response.setContentType("application/vnd.ms-excel");	//03版

			// 07版
			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
			
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
			workbook.write(response.getOutputStream());
			workbook.close();
		} catch (Exception e) {
			throw new ServiceException(e.getMessage());
		}
	}

	/**
	 * @Title importExcel
	 * @Description 导入Excel
	 * @param filePath   文件路径
	 * @param titleRows  标题行位置
	 * @param headerRows 表头行位置
	 * @param pojoClass  导入实体对象
	 * @return
	 * @author DSY
	 * @date 2021年2月2日 下午12:39:28
	 */
	public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
		if (StringUtils.isBlank(filePath)) {
			return null;
		}
		ImportParams params = new ImportParams();
		params.setTitleRows(titleRows);
		params.setHeadRows(headerRows);
		List<T> list = null;
		try {
			list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
		} catch (Exception e) {
			e.printStackTrace();
			throw new ServiceException("Excel导入失败：" + e.getMessage());
		}
		return list;
	}

	/**
	 * @Title importExcel
	 * @Description 导入文件
	 * @param file       文件
	 * @param titleRows  标题行位置
	 * @param headerRows 表头行位置
	 * @param pojoClass  导入实体
	 * @return
	 * @author DSY
	 * @date 2021年2月2日 下午12:41:28
	 */
	public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
		if (file == null) {
			return null;
		}
		ImportParams params = new ImportParams();
		params.setTitleRows(titleRows);
		params.setHeadRows(headerRows);
		List<T> list = null;
		try {
			list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
		} catch (Exception e) {
			throw new ServiceException("Excel导入失败：" + e.getMessage());
		}
		return list;
	}
}
